package net.yihang.miaosha.controller;

import net.yihang.miaosha.controller.result.CodeMsg;
import net.yihang.miaosha.domain.Goods;
import net.yihang.miaosha.domain.GoodsKey;
import net.yihang.miaosha.domain.MiaoshaUser;
import net.yihang.miaosha.domain.Order;
import net.yihang.miaosha.service.GoodsService;
import net.yihang.miaosha.service.OrderService;
import net.yihang.miaosha.service.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Controller
public class GoodsController {

    static final Logger logger = LoggerFactory.getLogger(GoodsController.class);

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private OrderService orderService;

    @RequestMapping("/goods/toGoods")
    public String toGoods(MiaoshaUser user, Model model) {
        logger.debug("Current User:" + user);

        List<Goods> goodsList = goodsService.findAll();
        model.addAttribute("goodsList", goodsList);
        return "goods";
    }

    @RequestMapping(value = "/goods/toGoodsDetail/{id}", produces = "text/html")
    public String toDetail(@PathVariable("id") long id, Model model, HttpServletRequest request, HttpServletResponse response) {
        Goods goods = goodsService.findById(id);
        model.addAttribute("goods", goods);
        model.addAttribute("id", id);
        return "detail";
    }

    @PostConstruct
    public void saveToRedis() {
        List<Goods> all = goodsService.findAll();
        int i = 1;
        for (Goods goods : all) {
            GoodsKey key = GoodsKey.idKey(goods.getId());
            goods.setUuid(""+i++);
            redisService.set(key, goods);


            GoodsKey key2 = GoodsKey.stockKey(goods.getId());
            // 使用list完成减库存
            /*if(goods.getStockCount()>0) {
                String[] values = new String[goods.getStockCount()];
                Arrays.fill(values, "1");
                redisService.del(key2);

                redisService.lpush(key2, values);
            }*/

            // 使用数字完成减库存
            redisService.del(key2);
            if(goods.getStockCount()>0) {
                redisService.set(key2, goods.getStockCount());
            }
        }
    }

    // <script src="/start.js?id=商品编号&t=時間戳">
    @RequestMapping("/start.js")
    @ResponseBody
    public String start(long id) {
        GoodsKey key = GoodsKey.idKey(id);
        Goods goods = redisService.get(key, Goods.class);
        if (goods == null) {
            return "";
        }
        Date now = new Date();
        if (goods.getStartDate().compareTo(now) <= 0 && goods.getEndDate().compareTo(now) >= 0) { //秒杀开始，才会返回url
            long t = (goods.getEndDate().getTime() - now.getTime())/1000;
            return "var started=true; var url='/goods/miaosha/" + goods.getId() + "/" + goods.getUuid() + "'; var time="+t;
        } else if (goods.getStartDate().compareTo(now) > 0) { // 未开始
            return "var started=false; var time=" + (goods.getStartDate().getTime() - now.getTime()) / 1000;
        } else { // 已经结束
            return "var started=false; var time=-1";
        }
    }

    /*// db 秒杀
    @RequestMapping("/goods/miaosha/{goodsId}/{uuid}")
    @ResponseBody
    public ResponseEntity<CodeMsg> miaosha(@PathVariable("goodsId") long goodsId, @PathVariable("uuid") String uuid, MiaoshaUser user) {
        // 检查是否非法抢购
        GoodsKey key = GoodsKey.idKey(goodsId);
        Goods goods = redisService.get(key, Goods.class);
        if(!goods.getUuid().equals(uuid)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(CodeMsg.QIANG_ERROR);
        }
        // 预判一下
        goods = goodsService.findById(goodsId);
        if(goods.getStockCount()<=0){
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(CodeMsg.STOCK_EMPTY);
        }

        // 减库存
        boolean success = goodsService.updateStock(goodsId);
        if(!success) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(CodeMsg.STOCK_EMPTY);
        }
        // 下单
        Order order = new Order();
        order.setUserId(user.getId());
        order.setGoodsId(goodsId);
        order.setGoodsCount(1);
        order.setGoodsName(goods.getGoodsName());
        order.setGoodsPrice(goods.getGoodsPrice());
        order.setCreateDate(new Date());
        order.setOrderChannel(Order.CHANNEL_ANDROID);
        order.setStatus(Order.STATUS_NO_PAY);
        orderService.saveOrder(order);

        return ResponseEntity.ok().body(CodeMsg.MIAOSHA_SUCCESS);
    }*/

    /*// redis 秒杀
    @RequestMapping("/goods/miaosha/{goodsId}/{uuid}")
    @ResponseBody
    public ResponseEntity<CodeMsg> miaosha(@PathVariable("goodsId") long goodsId, @PathVariable("uuid") String uuid, MiaoshaUser user) {
        // 检查是否非法抢购
        GoodsKey key = GoodsKey.idKey(goodsId);
        Goods goods = redisService.get(key, Goods.class);
        if(!goods.getUuid().equals(uuid)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(CodeMsg.QIANG_ERROR);
        }

        String value = redisService.rpop(GoodsKey.stockKey(goods.getId()));
        if(value == null) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(CodeMsg.STOCK_EMPTY);
        }
        // 下单
        Order order = new Order();
        order.setUserId(user.getId());
        order.setGoodsId(goodsId);
        order.setGoodsCount(1);
        order.setGoodsName(goods.getGoodsName());
        order.setGoodsPrice(goods.getGoodsPrice());
        order.setCreateDate(new Date());
        order.setOrderChannel(Order.CHANNEL_ANDROID);
        order.setStatus(Order.STATUS_NO_PAY);
        orderService.saveOrder(order);

        return ResponseEntity.ok().body(CodeMsg.MIAOSHA_SUCCESS);
    }*/

    // redis 分布式锁（悲观锁）秒杀
    @RequestMapping("/goods/miaosha/{goodsId}/{uuid}")
    @ResponseBody
    public ResponseEntity<CodeMsg> miaosha(@PathVariable("goodsId") long goodsId, @PathVariable("uuid") String uuid, MiaoshaUser user) {
        // 检查是否非法抢购
        GoodsKey key = GoodsKey.idKey(goodsId);
        Goods goods = redisService.get(key, Goods.class);
        if(!goods.getUuid().equals(uuid)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(CodeMsg.QIANG_ERROR);
        }

        CodeMsg result = redisService.miaosha(goodsId);
        if(CodeMsg.MIAOSHA_SUCCESS != result) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body(result);
        }

        // 下单
        Order order = new Order();
        order.setUserId(user.getId());
        order.setGoodsId(goodsId);
        order.setGoodsCount(1);
        order.setGoodsName(goods.getGoodsName());
        order.setGoodsPrice(goods.getGoodsPrice());
        order.setCreateDate(new Date());
        order.setOrderChannel(Order.CHANNEL_ANDROID);
        order.setStatus(Order.STATUS_NO_PAY);
        orderService.saveOrder(order);

        return ResponseEntity.ok().body(result);
    }
}
